package py.una.pol.ii.is2.dao.taller;

import java.math.BigInteger;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import py.una.pol.ii.is2.domain.taller.DetalleOrdenMantenimientoInsumo;
import py.una.pol.ii.is2.domain.taller.DetalleOrdenMantenimientoPlantilla;

/**
 * Clase que implementa la interfaz DetalleOrdenMantenimientoInsumoDAO
 * @author mbenitez
 * @date 30/04/2009
 */
@Stateless(mappedName="detalleOrdenInsumoDao")
public class DetalleOrdenMantenimientoInsumoDAOBean implements DetalleOrdenMantenimientoInsumoDAOLocal, DetalleOrdenMantenimientoInsumoDAORemote {

    /**
     * Manejador de instancias de entidades para recuperar instancias desde
     * el Persistence Context
     */
    @PersistenceContext
    private EntityManager em;
    @EJB
    private DetalleOrdenMantenimientoPlantillaDAOLocal detalleOrdenPlantillaDao;

    /**
     * Inserta una entidad de DetalleOrdenMantenimientoInsumo en la base de datos. 
     *
     * @param objeto Elemento a insertar
     * @return true para señalar que la operación se ejecutó con éxito, en otro caso false.
     * @throws java.lang.Exception
     */
    public boolean insert(DetalleOrdenMantenimientoInsumo objeto) throws Exception {
        boolean retorno = false;
        try {
            em.persist(objeto);
            detalleOrdenPlantillaDao.update(objeto.getDeoiDetalleOrden());
            calcularMontos(objeto.getDeoiDetalleOrden());
            retorno = true;
        } catch (Exception e) {
            throw e;
        } finally {
            return retorno;
        }
    }

    /**
     * Actualiza una entidad de DetalleOrdenMantenimientoInsumo, recibida como parámetro,
     * en la base de datos. 
     *
     * @param objeto Elemento a editar
     * @return true para señalar que la operación se ejecutó con éxito, en otro caso false.
     * @throws java.lang.Exception
     */
    public boolean update(DetalleOrdenMantenimientoInsumo objeto) throws Exception {
        boolean retorno = false;
        try {
            em.merge(objeto);
            detalleOrdenPlantillaDao.update(objeto.getDeoiDetalleOrden());
            calcularMontos(objeto.getDeoiDetalleOrden());
            retorno = true;
        } catch (Exception e) {
            throw e;
        } finally {
            return retorno;
        }
    }

    /**
     * Elimina una entidad de DetalleOrdenMantenimientoInsumo recibida como parametro
     * en la base de datos. 
     *
     * @param objeto Elemento a eliminar
     * @return true para señalar que la operación se ejecutó con éxito, en otro caso false.
     * @throws java.lang.Exception
     */
    public boolean delete(DetalleOrdenMantenimientoInsumo objeto) throws Exception {
        boolean retorno = false;
        try {
            DetalleOrdenMantenimientoInsumo mgdObjeto = em.merge(objeto);
            DetalleOrdenMantenimientoPlantilla detallePlantilla = mgdObjeto.getDeoiDetalleOrden();
            em.remove(mgdObjeto);
            detalleOrdenPlantillaDao.update(detallePlantilla);
            calcularMontos(detallePlantilla);
            retorno = true;
        } catch (Exception e) {
            throw e;
        } finally {
            return retorno;
        }
    }

    private boolean calcularMontos(DetalleOrdenMantenimientoPlantilla detalle) throws Exception {
        boolean retorno = false;
        BigInteger monto = BigInteger.ZERO;
        try {
            for (DetalleOrdenMantenimientoInsumo detalleInsumo : detalle.getDetalleOrdenMantenimientoInsumoCollection()) {
                monto = monto.add(detalleInsumo.getDeoiPrecio().multiply(new BigInteger(detalleInsumo.getDeoiCantidad().toString())));
            }
            detalle.setDeopCostoInsumos(monto);
            retorno = detalleOrdenPlantillaDao.update(detalle);
        } catch (Exception e) {
            throw e;
        } finally {
            return retorno;
        }
    }

    /**
     * Busca un registro de la tabla DetalleOrdenMantenimientoInsumo por el codigo de la misma.
     * Utiliza el NamedQuery <b>DetalleOrdenMantenimientoInsumo.findByDeoiCod</b> para su efecto.
     *
     * @param codObjeto Código de DetalleOrdenMantenimientoInsumo buscado
     * @return retorno DetalleOrdenMantenimientoInsumo encontrado, en otro caso null.
     * @throws java.lang.Exception
     */
    public DetalleOrdenMantenimientoInsumo find(Integer codObjeto) throws Exception {
        DetalleOrdenMantenimientoInsumo retorno = null;
        try {
            Query q = em.createNamedQuery("DetalleOrdenMantenimientoInsumo.findByDeoiCod");
            q.setParameter("deoiCod", codObjeto);
            retorno = (DetalleOrdenMantenimientoInsumo) q.getSingleResult();
        } catch (Exception e) {
            throw e;
        } finally {
            return retorno;
        }
    }

    /**
     * Devuelve todas las DetalleOrdenMantenimientoInsumo en caso de que el parametro condicion
     * sea o bien <b>null</b> o <b>vacio</b>, y aquellas que coincidan con la condicion
     * comenzando con la palabra clave <b>where</b>.
     * Las entidades son devueltas ordenadas por la clave primaria.
     *
     *
     * @param condicion Restricción para la selección de resultados
     * @return retorno Lista de resultados arrojados por la ejecución de la consulta, en otro caso null.
     * @throws java.lang.Exception
     */
    public List<DetalleOrdenMantenimientoInsumo> getListaDetalleOrdenMantenimientoInsumos(String condicion) throws Exception {
        List<DetalleOrdenMantenimientoInsumo> retorno = null;
        Query q = null;
        try {
            if (condicion == null || condicion.length() == 0) {
                q = em.createNamedQuery("DetalleOrdenMantenimientoInsumo.findAll");
            } else {
                q = em.createQuery("select deoi from DetalleOrdenMantenimientoInsumo deoi " + condicion + " order by deoi.deoiCod");
            }
            // recuperamos la lista
            retorno = q.getResultList();
        } catch (Exception e) {
            throw e;
        } finally {
            return retorno;
        }
    }

    /**
     * 
     * @param codPlantilla
     * @return
     * @throws java.lang.Exception
     */
    public List<DetalleOrdenMantenimientoInsumo> getListaDetalleOrdenMantenimientoInsumosByCodDetallePlantilla(DetalleOrdenMantenimientoPlantilla codPlantilla) throws Exception {
        List<DetalleOrdenMantenimientoInsumo> retorno = null;
        Query q = null;
        try {
            if (codPlantilla != null) {
                q = em.createQuery("select deoi from DetalleOrdenMantenimientoInsumo deoi where deoi.deoiDetalleOrden = :codDetallePlantilla");
                q.setParameter("codDetallePlantilla", codPlantilla);
                // recuperamos la lista
                retorno = q.getResultList();
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        } finally {
            return retorno;
        }

    }
}
